#include "thread.h"
#include "util.h"
#include "log.h"


// Done

static thread_local Thread* t_thread = nullptr;
static thread_local std::string t_thread_name = "UNKNOWN";



Thread* Thread::GetThis()
{
    return t_thread;
}

const std::string& Thread::GetName()
{
    return t_thread_name;
}

void Thread::SetName(const std::string& thread_name)
{
    if(thread_name.empty()) return;

    if(t_thread) t_thread->m_thread_name = thread_name;
    
    t_thread_name = thread_name;
}

Thread::Thread(const std::function<void()>& cb,const std::string& thread_name)
    :m_thread_name(thread_name)
    ,m_cb(cb)
{
    if(thread_name.empty()) m_thread_name = "UNKNOWN";
    int ret = pthread_create(&m_thread,nullptr,&Thread::run,this);
    if(ret)
    {
        LOG(ERROR,"pthread_create thread failed, ret = %d thread_name = %s",ret,thread_name);
        throw std::logic_error("pthread_create error");
    }
    // 构造函数在创建线程后会一直阻塞，直到线程函数运行并且通知信号量，构造函数才会返回，而构造函数一旦返回，就说明线程函数已经在执行了。
    m_semaphore.wait();
}

Thread::~Thread()
{
    if(m_thread)
    {
        pthread_detach(m_thread);
    }
}

void Thread::join()
{
    if(m_thread)
    {
        int ret = pthread_join(m_thread,nullptr);
        if(ret)
        {
            LOG(ERROR,"pthread_join thread failed,ret = %d thread_name = %s",ret,m_thread_name);
            throw std::logic_error("pthread_join error");
        }
        m_thread = 0;
    }
}

void* Thread::run(void* arg)
{
    Thread* thread = static_cast<Thread*>(arg);
    t_thread = thread;
    t_thread_name = thread->m_thread_name;
    thread->m_thread_id = GetThreadId();

    // 用于设置一个运行中的线程的名称
    pthread_setname_np(pthread_self(),thread->m_thread_name.substr(0,15).c_str());

    std::function<void()> cb;
    cb.swap(thread->m_cb);

    thread->m_semaphore.notify();
    
    cb();

    return nullptr;
}